package org.codetranslators.compiler.tiger;

import java.util.LinkedHashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;

public class ErrorHandler 
{
	public static final String TP_MISMATCH_ASSGN = "Type mismatch in assignment expression";
	public static final String TP_MISMATCH_OPER= "Type mismatch in operator expression";
	public static final String BREAK_NOT_IN_LOOP = "\"break\" is not inside a loop";
	public static final String THE_FUNCTION = "The function ";
	public static final String NOT_DEFINED = " is not defined";
	public static final String THE_VARIABLE = "The variable ";
	public static final String THE_TYPE = "The type ";
	public static final String IF_TEST_EXPR = "The test in the if condition ";
	public static final String MUST_BE_INT = " does not evaluate to an integer value.";
	public static final String FORLOOP_HIVALUE_MUST_BE_INT = 
							"The high value of the for loop does not evaluate to an integer value";
	public static final String FORLOOP_BODY_NULL = "The body of the for loop does not evaluate to a void value";
	public static final String LEFT_OPERAND = "The left operand of  ";
	public static final String RIGHT_OPERAND = "The right operand of  ";
	public static final String FUNC_RETTYPE_NOT_COMPATIBLE = 
		"The return type of the function is not compatible with the type of the expression of the body.";
	public static final String INIT_EXPR_TYPE_NOT_FOUND = 
		"The initializing expression does not evaluate to a known type";
	public static final String TYPE_MISMATCH_VARDEC = "Type mismatch in variable declaration.";
	public static final String ALREADY_DEFINED = " has already been defined in the current scope.";
	public static final String IF_THEN_ELSE_TYPE_INCOMPATIBLE = 
		"The type of the \"then\" and \"else\" expressions do not match";
	public static final String FIELD_EXP_MISMATCH = "The field type does not match the type of the initializing expression";
	public static final String FIELD_NAME = "The field name ";
	public static final String THE_ARGUMENT_NUM = "The argument type at postion ";
	public static final String PARAM_MISMATCH = " does not match the paramater type";
	public static final String NUM_ARGS_MISMATCH = "The number of arguments do not match the number of parameters in the function definition";
	public static final String ARRAY_INDEX_NOT_INT = "The expression of the array index does not evaluate to an int";
	public static final String ARRAY_SIZE_NOT_INT = "The array size does not evaluate to an int value";
	public static final String ARRAY_INIT_VALUE_MISMATCH = "The initial value specified for the array does not match it's base type"; 
	public static final String THE_FIELD_NAME = "The field name ";
	public static final String NOT_RECORD = " is not a record type.";
	public static final String NOT_ARRAY = " is not an array type.";
	public static final String WHILE_TEST_NOT_INT = "The test in the while expression does not evaluate to an integer value";
	public static final String WHILE_BODY_NOT_VOID = "The body of the while loop should not evaluate to any type";
	
	private LinkedHashMap lineNumVsMessages;
	
	private static ErrorHandler singletonInstance;
	
	private ErrorHandler()
	{
		lineNumVsMessages = new LinkedHashMap();
	}
	
	public static ErrorHandler getInstance()
	{
		if(singletonInstance == null)
			singletonInstance = new ErrorHandler();
		return singletonInstance;
	}
	
	public void addError(int lineNum, String msg)
	{
		System.out.println("Adding error at line " + lineNum + " with message: " + msg);
		if(singletonInstance.lineNumVsMessages.get("" + lineNum) == null)
			singletonInstance.lineNumVsMessages.put("" + lineNum, msg);
	}
	
	public void addError(int lineNum, String msg1, String str, String msg2)
	{
		String msg = msg1 + str + msg2;
		addError(lineNum, msg);
	}
	
	public int getNumErrors()
	{
		return singletonInstance.lineNumVsMessages.size();
	}
	
	public void displayResult()
	{
		if(getNumErrors() == 0)
		{
			System.out.println("Compiled successfully");
		}
		else
		{
			Set entries = singletonInstance.lineNumVsMessages.entrySet();
			Iterator iter = entries.iterator();
			while(iter.hasNext())
			{
				Map.Entry entry = (Map.Entry) iter.next();
				String lineNum = (String)entry.getKey();
				String msg = (String) entry.getValue();
				
				msg = "Line " + lineNum + ": " + msg;
				System.out.println(msg);
			}
		}
	}

}
